﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Windows.Forms;
using System.Drawing;

using ESRI.ArcGIS.Analyst3D;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.ConversionTools;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.DataSourcesRaster;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geoprocessor;
using ESRI.ArcGIS.Geoprocessing;
using ESRI.ArcGIS.NetworkAnalyst;


namespace SPAS
{
    static class Utils
    {

        #region 文件读取相关 汤焱编写
        /// <summary>
        /// 加载Shape文件至图层
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        static public ILayer LoadShapeFile(string filePath)
        {
            // 文件目录
            string workSpacePath = System.IO.Path.GetDirectoryName(filePath);
            // 文件名
            string shapeFileName = System.IO.Path.GetFileName(filePath);

            // 打开工作空间
            IWorkspaceFactory workSpaceFactory = new ShapefileWorkspaceFactoryClass();
            IWorkspace workSpace = workSpaceFactory.OpenFromFile(workSpacePath, 0);
            IFeatureWorkspace featureWorkSpace = workSpace as IFeatureWorkspace;

            // 得到要素类
            IFeatureClass featureClass = featureWorkSpace.OpenFeatureClass(shapeFileName);
            IFeatureLayer featureLayer = new FeatureLayerClass();
            featureLayer.FeatureClass = featureClass;
            featureLayer.Name = (featureClass as IDataset).Name;
            ILayer layer = featureLayer as ILayer;

            return layer;
        }

        /// <summary>
        /// 加载栅格数据至图层
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        static public ILayer LoadRasterFile(string filePath)
        {
            // 文件目录
            string workSpacePath = System.IO.Path.GetDirectoryName(filePath);
            // 文件名
            string rasterFileName = System.IO.Path.GetFileName(filePath);

            // 打开工作空间
            IWorkspaceFactory workSpaceFactory = new RasterWorkspaceFactoryClass();
            IWorkspace workSpace = workSpaceFactory.OpenFromFile(workSpacePath, 0);
            IRasterWorkspace rasterWorkSpace = workSpace as IRasterWorkspace;

            // 得到栅格数据集
            IRasterDataset rasterDataset = rasterWorkSpace.OpenRasterDataset(rasterFileName);

            // 影像金字塔判断与创建
            IRasterPyramid3 rasterPyrmid;
            rasterPyrmid = rasterDataset as IRasterPyramid3;
            if (rasterPyrmid != null)
            {
                if (!(rasterPyrmid.Present))
                {
                    rasterPyrmid.Create(); // 创建金字塔
                }
            }

            IRaster raster;
            raster = rasterDataset.CreateDefaultRaster();
            IRasterLayer rasterLayer = new RasterLayerClass();
            rasterLayer.CreateFromRaster(raster);
            ILayer layer = rasterLayer as ILayer;
            return layer;
        }

        /// <summary>
        /// MultiPatch转栅格数据
        /// </summary>
        /// <param name="multipatch"></param>
        /// <returns></returns>
        static public IRaster ConvertMultiPatchToRaster(IFeatureClass multipatch, string outFilePath, double cellSize = 0.5)
        {
            // 获取目录名和文件名
            string workSpacePath = System.IO.Path.GetDirectoryName(outFilePath);
            string rasterFileName = System.IO.Path.GetFileName(outFilePath);

            // 打开工作空间
            IWorkspaceFactory workSpaceFactory = new RasterWorkspaceFactoryClass();
            IWorkspace workSpace = workSpaceFactory.OpenFromFile(workSpacePath, 0);
            IRasterWorkspace2 rasterWorkSpace = workSpace as IRasterWorkspace2;

            IPoint pPoint = new PointClass();
            pPoint.PutCoords(15.0, 15.0);

            // 得到栅格数据集
            IRasterDataset rasterDataset = null;
            try
            {
                rasterDataset = rasterWorkSpace.OpenRasterDataset(rasterFileName);
            }
            catch
            {
            }

            if (rasterDataset != null) // 删除存在的栅格数据集
            {
                IDataset dataset = rasterDataset as IDataset;
                if (dataset.CanDelete())
                    try
                    {
                        dataset.Delete();
                    }
                    catch
                    {
                        MessageBox.Show("删除栅格数据集错误");
                    }
            }
            rasterDataset = rasterWorkSpace.CreateRasterDataset(rasterFileName, "TIFF", pPoint, 100, 100, 10, 10, 1, rstPixelType.PT_UCHAR);

            MultipatchToRaster mtr = new MultipatchToRaster(multipatch, rasterDataset);
            mtr.cell_size = cellSize;

            Geoprocessor gp = new Geoprocessor();
            gp.OverwriteOutput = true;
            gp.Execute(mtr, null);

            return (LoadRasterFile((string)mtr.out_raster) as RasterLayer).Raster;
        }

        /// <summary>
        /// MultiPatch转多边形面要素
        /// </summary>
        /// <param name="multipatch"></param>
        /// <param name="outName"></param>
        /// <returns></returns>
        static public IFeatureClass ConvertMultiPatchToPolygonFeatures(IFeatureClass multipatch, string outFilePath, ISpatialReference spatialReference)
        {
            IFeatureCursor featureCursor = multipatch.Search(null, false);
            IFeature feature = featureCursor.NextFeature();

            IFeatureLayer footprintFeatureLayer = AddFeatureLayer(outFilePath, esriGeometryType.esriGeometryPolygon, feature.Fields);

            // 将要素类转换为dataset
            IDataset dataset = footprintFeatureLayer.FeatureClass as IDataset;
            // 获得工作空间
            IWorkspace workSpace = dataset.Workspace;
            // 获得编辑状态
            IWorkspaceEdit wsedit = workSpace as IWorkspaceEdit;
            wsedit.StartEditing(true);
            wsedit.StartEditOperation();

            IFeature tempFeature = null;

            IFeatureClass sourceFeatureClass = footprintFeatureLayer.FeatureClass;
            while (feature != null)
            {
                IGeometry geometry = feature.ShapeCopy;
                IMultiPatch multiPatch = geometry as IMultiPatch;
                IEnvelope envelope = multiPatch.Envelope;
                ITopologicalOperator topologicalOperator = geometry as ITopologicalOperator;
                IGeometry newGeometry = topologicalOperator.Intersect(envelope, esriGeometryDimension.esriGeometry2Dimension);

                if (wsedit.IsBeingEdited())
                {
                    tempFeature = sourceFeatureClass.CreateFeature();
                    tempFeature.Shape = newGeometry;
                    for (int i = 0; i < feature.Fields.FieldCount; i++)
                    {
                        if (feature.Fields.get_Field(i).Type != esriFieldType.esriFieldTypeGeometry && feature.Fields.get_Field(i).Type != esriFieldType.esriFieldTypeOID)
                        {
                            tempFeature.set_Value(i, feature.get_Value(i));
                        }
                    }

                    tempFeature.Store();
                }
                feature = featureCursor.NextFeature();
            }

            // 停止编辑
            wsedit.StopEditing(true);
            wsedit.StartEditOperation();

            System.Runtime.InteropServices.Marshal.ReleaseComObject(wsedit);

            // 添加要素空间参考
            IGeoDataset geoDataset = (footprintFeatureLayer.FeatureClass) as IGeoDataset;
            IGeoDatasetSchemaEdit geoDatasetSchemaEdit = geoDataset as IGeoDatasetSchemaEdit;
            if (geoDatasetSchemaEdit.CanAlterSpatialReference)
            {
                geoDatasetSchemaEdit.AlterSpatialReference(spatialReference);
            }

            return footprintFeatureLayer.FeatureClass;
        }

        /// <summary>
        /// 判断图层数据是否为栅格数据
        /// </summary>
        /// <param name="layer"></param>
        /// <returns></returns>
        static public bool IsRasterLayer(ILayer layer)
        {
            IRasterLayer rasterLayer = new RasterLayer();
            rasterLayer = layer as IRasterLayer;
            return rasterLayer != null;
        }

        /// <summary>
        /// 获取临时文件目录+文件名
        /// </summary>
        /// <returns></returns>
        static public string GetTempFilePath()
        {
            string tempName = System.IO.Path.GetFileName(System.IO.Path.GetTempFileName());
            string tempPath = System.Windows.Forms.Application.StartupPath + "\\Temp\\";

            if (!System.IO.Directory.Exists(tempPath))
            {
                System.IO.Directory.CreateDirectory(tempPath);
            }

            return tempPath + tempName;
        }

        /// <summary>
        /// 获取临时文件目录
        /// </summary>
        /// <returns></returns>
        static public string GetTempDirectory()
        {
            string tempPath = System.Windows.Forms.Application.StartupPath + "\\Temp\\";
            if (!System.IO.Directory.Exists(tempPath))
            {
                System.IO.Directory.CreateDirectory(tempPath);
            }
            return tempPath;
        }

        /// <summary>
        /// 递归删除文件夹
        /// </summary>
        /// <param name="tempDir"></param>
        static public void DeleteDirectory(string tempDir)
        {

            DirectoryInfo dir = new DirectoryInfo(tempDir);
            FileSystemInfo[] fileinfo = dir.GetFileSystemInfos();  //返回目录中所有文件和子目录
            foreach (FileSystemInfo i in fileinfo)
            {
                try
                {
                    if (i is DirectoryInfo)            //判断是否文件夹
                    {
                        DirectoryInfo subdir = new DirectoryInfo(i.FullName);
                        subdir.Delete(true);          //删除子目录和文件
                    }
                    else
                    {
                        File.Delete(i.FullName);      //删除指定文件
                    }
                }
                catch (Exception e)
                {
                    MessageBox.Show("文件夹" + tempDir + "删除发生错误！", "错误\n" + e.Message, MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
                }
            }

        }
        #endregion

        #region 太阳高度角、方位角计算相关 柳伟佳编写
        /// <summary>
        /// 计算太阳高度角、方位角
        /// </summary>
        /// <param name="time"></param>
        /// <param name="latitude"></param>
        /// <param name="longitude"></param>
        static public void ComputeAltitudeAndAzimuth(DateTime time, double latitude, out double altitude, out double azimuth)
        {
            Console.WriteLine(time.Hour);
            double h = AngleToRadian((time.Hour + time.Minute / 60.0 + time.Second / 3600.0 - 12) * 15);
            double delta = AngleToRadian(-23.44 * Math.Cos(2 * Math.PI / 365 * (time.DayOfYear + 10)));
            double sinAltitude = Math.Cos(h) * Math.Cos(delta) * Math.Cos(AngleToRadian(latitude)) + Math.Sin(delta) * Math.Sin(AngleToRadian(latitude));
            altitude = RadianToAngle(Math.Asin(sinAltitude));
            double cosAzimuth = (Math.Sin(delta) - sinAltitude * Math.Sin(AngleToRadian(latitude))) / Math.Cos(AngleToRadian(altitude)) / Math.Cos(AngleToRadian(latitude));
            if (cosAzimuth < -1)
                cosAzimuth = -1;

            if (h < 0)
                azimuth = RadianToAngle(Math.Acos(cosAzimuth));
            else
                azimuth = 360 - RadianToAngle(Math.Acos(cosAzimuth));
        }

        /// <summary>
        /// 角度转弧度
        /// </summary>
        /// <param name="angle"></param>
        /// <returns></returns>
        static public double AngleToRadian(double angle)
        {
            return angle / 180 * Math.PI;
        }

        /// <summary>
        /// 弧度转角度
        /// </summary>
        /// <param name="radian"></param>
        /// <returns></returns>
        static public double RadianToAngle(double radian)
        {
            return radian / Math.PI * 180;
        }

        /// <summary>
        /// 资源回收
        /// </summary>
        /// <param name="o"></param>
        static public void NAR(object o)
        {
            try
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(o);
            }
            catch
            {
            }
            finally
            {
                o = null;
            }
        }
        #endregion

        #region 测角交会相关 汤焱编写
        /// <summary>
        /// 获取要素图层
        /// </summary>
        /// <param name="mapControl"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        static public IFeatureLayer GetLayerByName(IMapControl3 mapControl, string name)
        {
            int index = -1;
            for (int i = 0; i < mapControl.LayerCount; i++)
            {
                if (mapControl.get_Layer(i).Name == name)
                {
                    index = i;
                    break;
                }
            }

            IFeatureLayer featureLayer = null;
            if (index != -1)
                featureLayer = mapControl.get_Layer(index) as IFeatureLayer;
            return featureLayer;
        }

        /// <summary>
        /// 添加要素图层
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        static public IFeatureLayer AddFeatureLayer(string outFilePath, esriGeometryType type, IFields fields = null, bool IsGDB = false)
        {
            // 获取目录名和文件名
            string workSpacePath = System.IO.Path.GetDirectoryName(outFilePath);
            string shapeFileName = System.IO.Path.GetFileName(outFilePath);

            IWorkspaceFactory workSpaceFactory = null;
            if (IsGDB)
                workSpaceFactory = new FileGDBWorkspaceFactory();
            else
                workSpaceFactory = new ShapefileWorkspaceFactoryClass();
            
            IWorkspace workSpace = workSpaceFactory.OpenFromFile(workSpacePath, 0);
            IFeatureWorkspace featureWorkSpace = workSpace as IFeatureWorkspace;

            // 新建要素类
            if (fields == null)
            {
                IFieldsEdit fieldsEdit = new Fields() as IFieldsEdit;

                IFieldEdit objectidField = new Field() as IFieldEdit;
                objectidField.Name_2 = "OBJECTID";
                objectidField.AliasName_2 = "oid";
                objectidField.Type_2 = esriFieldType.esriFieldTypeOID;
                fieldsEdit.AddField(objectidField);

                IGeometryDefEdit geometryDef = new GeometryDef() as IGeometryDefEdit;
                geometryDef.GeometryType_2 = type;
                IFieldEdit geometryField = new Field() as IFieldEdit;
                geometryField.Name_2 = "SHAPE";
                geometryField.AliasName_2 = "shape";
                geometryField.Type_2 = esriFieldType.esriFieldTypeGeometry;
                geometryField.GeometryDef_2 = geometryDef;
                fieldsEdit.AddField(geometryField);

                fields = fieldsEdit as IFields;
            }
            else
            {
                IFieldsEdit fieldsEdit = new Fields() as IFieldsEdit;

                IFieldEdit objectidField = new Field() as IFieldEdit;
                objectidField.Name_2 = "OBJECTID";
                objectidField.AliasName_2 = "oid";
                objectidField.Type_2 = esriFieldType.esriFieldTypeOID;
                fieldsEdit.AddField(objectidField);

                IGeometryDefEdit geometryDef = new GeometryDef() as IGeometryDefEdit;
                geometryDef.GeometryType_2 = type;
                IFieldEdit geometryField = new Field() as IFieldEdit;
                geometryField.Name_2 = "SHAPE";
                geometryField.AliasName_2 = "shape";
                geometryField.Type_2 = esriFieldType.esriFieldTypeGeometry;
                geometryField.GeometryDef_2 = geometryDef;
                fieldsEdit.AddField(geometryField);

                for (int i = 0; i < fields.FieldCount; i++)
                {
                    if (fields.get_Field(i).Type != esriFieldType.esriFieldTypeOID && fields.get_Field(i).Type != esriFieldType.esriFieldTypeGeometry)
                        fieldsEdit.AddField(fields.get_Field(i));
                }

                fields = null;
                fields = fieldsEdit as IFields;
            }

            IFeatureClassDescription fcd = new FeatureClassDescription() as IFeatureClassDescription;
            IObjectClassDescription ocd = (IObjectClassDescription)fcd;

            IFeatureClass featureClass = featureWorkSpace.CreateFeatureClass(
                shapeFileName,
                fields,
                ocd.InstanceCLSID,
                ocd.ClassExtensionCLSID,
                esriFeatureType.esriFTSimple,
                fcd.ShapeFieldName,
                null);

            IFeatureLayer featureLayer = new FeatureLayerClass();
            featureLayer.FeatureClass = featureClass;
            featureLayer.Name = (featureClass as IDataset).Name;

            return featureLayer;
        }

        static public void ExportFeature(IFeatureClass apFeatureClass, string ExportFilePath, string ExportFileShortName)
        {
            if (apFeatureClass == null)
            {
                MessageBox.Show("导出失败", "系统提示");
                return;

            }

            //设置导出要素类的参数
            IFeatureClassName pOutFeatureClassName = new FeatureClassNameClass();
            IDataset pOutDataset = (IDataset)apFeatureClass;
            pOutFeatureClassName = (IFeatureClassName)pOutDataset.FullName;
            //创建一个输出shp文件的工作空间
            IWorkspaceFactory pShpWorkspaceFactory = new ShapefileWorkspaceFactory();
            IWorkspaceName pInWorkspaceName = new WorkspaceNameClass();
            pInWorkspaceName = pShpWorkspaceFactory.Create(ExportFilePath, ExportFileShortName, null, 0);

            //创建一个要素集合
            IFeatureDatasetName pInFeatureDatasetName = null;
            //创建一个要素类
            IFeatureClassName pInFeatureClassName = new FeatureClassNameClass();
            IDatasetName pInDatasetClassName;
            pInDatasetClassName = (IDatasetName)pInFeatureClassName;
            pInDatasetClassName.Name = ExportFileShortName;//作为输出参数
            pInDatasetClassName.WorkspaceName = pInWorkspaceName;

            //通过FIELDCHECKER检查字段的合法性，为输出SHP获得字段集合
            long iCounter;
            IFields pOutFields, pInFields;
            IFieldChecker pFieldChecker;
            IField pGeoField;
            IEnumFieldError pEnumFieldError = null;
            pInFields = apFeatureClass.Fields;
            pFieldChecker = new FieldChecker();
            pFieldChecker.Validate(pInFields, out pEnumFieldError, out pOutFields);
            //通过循环查找几何字段
            pGeoField = null;
            for (iCounter = 0; iCounter < pOutFields.FieldCount; iCounter++)
            {
                if (pOutFields.get_Field((int)iCounter).Type == esriFieldType.esriFieldTypeGeometry)
                {
                    pGeoField = pOutFields.get_Field((int)iCounter);
                    break;
                }
            }
            //得到几何字段的几何定义
            IGeometryDef pOutGeometryDef;
            IGeometryDefEdit pOutGeometryDefEdit;
            pOutGeometryDef = pGeoField.GeometryDef;
            //设置几何字段的空间参考和网格
            pOutGeometryDefEdit = (IGeometryDefEdit)pOutGeometryDef;
            pOutGeometryDefEdit.GridCount_2 = 1;
            pOutGeometryDefEdit.set_GridSize(0, 1500000);
            try
            {
                //开始导入
                IFeatureDataConverter pShpToClsConverter = new FeatureDataConverterClass();
                pShpToClsConverter.ConvertFeatureClass(pOutFeatureClassName, null, pInFeatureDatasetName, pInFeatureClassName, pOutGeometryDef, pOutFields, "", 1000, 0);
                MessageBox.Show("导出成功！");
            }
            catch
            {
            }
        }

        /// <summary>
        /// 向要素图层中添加几何图形
        /// </summary>
        /// <param name="geo"></param>
        /// <param name="layer"></param>
        static public void AddGeometry(IGeometry geo, IFeatureLayer layer)
        {
            // 将要素类转换为dataset
            IDataset myDataset = layer.FeatureClass as IDataset;
            // 获得工作空间
            IWorkspace myWorkspace = myDataset.Workspace;
            // 获得编辑状态
            IWorkspaceEdit wsedit = myWorkspace as IWorkspaceEdit;
            wsedit.StartEditing(true);
            wsedit.StartEditOperation();

            IFeature feature = null;

            IFeatureClass sourceFeatureClass = layer.FeatureClass;
            if (wsedit.IsBeingEdited())
            {
                feature = sourceFeatureClass.CreateFeature();
                feature.Shape = geo;
                feature.Store();
            }

            // 停止编辑
            wsedit.StopEditing(true);
            wsedit.StartEditOperation();

            System.Runtime.InteropServices.Marshal.ReleaseComObject(wsedit);
        }

        /// <summary>
        /// 改变点要素图层的显示
        /// </summary>
        /// <param name="layer"></param>
        /// <param name="color"></param>
        /// <param name="style"></param>
        /// <param name="size"></param>
        static public void ChangePointLayerStyle(ILayer layer, Color color, esriSimpleMarkerStyle style, double size)
        {

            ISimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbol();
            simpleMarkerSymbol.Color = ColorToIColor(color);

            simpleMarkerSymbol.Style = style;
            simpleMarkerSymbol.Size = size;
            ISimpleRenderer render = new SimpleRenderer();
            render.Symbol = simpleMarkerSymbol as ISymbol;
            (layer as IGeoFeatureLayer).Renderer = render as IFeatureRenderer;
        }

        static public void ChangePolygonLayerStyle(ILayer layer, Color lineColor, double lineWidth, Color fillColor)
        {
            ILineSymbol lSymbol = new SimpleLineSymbolClass();
            lSymbol.Color = ColorToIColor(lineColor);
            lSymbol.Width = lineWidth;

            ISimpleFillSymbol simpleFillSymbol = new SimpleFillSymbolClass();
            simpleFillSymbol.Color = ColorToIColor(fillColor);
            simpleFillSymbol.Style = esriSimpleFillStyle.esriSFSSolid;
            simpleFillSymbol.Outline = lSymbol;


            ISimpleRenderer render = new SimpleRenderer();
            render.Symbol = simpleFillSymbol as ISymbol;
            (layer as IGeoFeatureLayer).Renderer = render as IFeatureRenderer;
        }

        /// <summary>
        /// 工具函数color2Icolor
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        static public IColor ColorToIColor(Color c)
        {
            IColor c1 = new RgbColor();
            c1.RGB = c.R + c.G * 256 + c.B * 65536;
            return c1;
        }

        /// <summary>
        /// 获取要素类中的第一个要素
        /// </summary>
        /// <param name="featureClass"></param>
        /// <returns></returns>
        static public IFeature GetFirstFeature(IFeatureClass featureClass)
        {
            IFeatureCursor featureCursor = featureClass.Search(null, false);
            IFeature feature = featureCursor.NextFeature();
            return feature;
        }
        #endregion

        #region GNSS相关 季旻编写

        /// <summary>
        /// 在要素类中添加字段
        /// </summary>
        /// <param name="featureClass"></param>
        /// <param name="fieldName"></param>
        /// <param name="fieldType"></param>
        static public void AddFieldToFeatureClass(IFeatureClass featureClass, string fieldName, esriFieldType fieldType)
        {
            double idx;
            idx = featureClass.Fields.FindField(fieldName);

            if (idx < 0)
            {
                IFields fields = featureClass.Fields;
                IFieldsEdit fieldsEdit = fields as IFieldsEdit;

                IField field = new FieldClass();
                IFieldEdit fieldEdit = field as IFieldEdit;
                fieldEdit.Name_2 = fieldName;
                fieldEdit.Type_2 = fieldType;

                featureClass.AddField(fieldEdit);
            }
        }

        //private IFeatureLayer CreateShpFromLine(string xjFilePath)
        //{

        //    int index = xjFilePath.LastIndexOf('\\');
        //    string xjFolder = xjFilePath.Substring(0, index);
        //    string xjShapeName = xjFilePath.Substring(index + 1);
        //    IWorkspaceFactory xjWsF = new ShapefileWorkspaceFactoryClass();
        //    IFeatureWorkspace xjFWs = (IFeatureWorkspace)xjWsF.OpenFromFile(xjFolder, 0);

        //    if (File.Exists(xjFilePath))
        //    {
        //        File.Delete(xjFolder + "\\line.shp");
        //        File.Delete(xjFolder + "\\line.dbf");
        //        File.Delete(xjFolder + "\\line.prj");
        //        File.Delete(xjFolder + "\\line.shx");
        //    }

        //    IFields xjFields = new FieldsClass();
        //    IFieldsEdit xjFieldsEdit;
        //    xjFieldsEdit = (IFieldsEdit)xjFields;

        //    IField xjField = new FieldClass();
        //    IFieldEdit xjFieldEdit = (IFieldEdit)xjField;
        //    xjFieldEdit.Name_2 = "Shape";
        //    xjFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
        //    IGeometryDef xjGeometryDef = new GeometryDefClass();
        //    IGeometryDefEdit xjGDefEdit = (IGeometryDefEdit)xjGeometryDef;
        //    xjGDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPolyline;
        //    //定义坐标系
        //    //ISpatialReferenceFactory pSRF = new SpatialReferenceEnvironmentClass();
        //    //ISpatialReference pSpatialReference = pSRF.CreateProjectedCoordinateSystem((int)esriSRProjCS4Type.esriSRProjCS_Beijing1954_3_Degree_GK_CM_114E);
        //    xjGDefEdit.SpatialReference_2 = this.axMapControl1.ActiveView.FocusMap.SpatialReference;//pSpatialReference;

        //    xjFieldEdit.GeometryDef_2 = xjGeometryDef;
        //    xjFieldsEdit.AddField(xjField);

        //    IFeatureClass xjFeatureClass;
        //    xjFeatureClass = xjFWs.CreateFeatureClass(xjShapeName, xjFields, null, null, esriFeatureType.esriFTSimple, "Shape", "");

        //    IPoint startPoint = new PointClass();
        //    IPoint stopPoint = new PointClass();
        //    IPolyline xjLine = new PolylineClass();
        //    for (int j = 0; j < point_start_x.Count; j++)
        //    {

        //        startPoint.X = Convert.ToDouble(point_start_x[j]);
        //        startPoint.Y = Convert.ToDouble(point_start_y[j]);
        //        stopPoint.X = Convert.ToDouble(point_stop_x[j]);
        //        stopPoint.Y = Convert.ToDouble(point_stop_y[j]);

        //        xjLine.FromPoint = startPoint;
        //        xjLine.ToPoint = stopPoint;
        //        IFeatureBuffer xjFeature = xjFeatureClass.CreateFeatureBuffer();
        //        IFeatureCursor featureCursor = xjFeatureClass.Insert(true);

        //        xjFeature.Shape = xjLine;
        //        xjFeature.set_Value(xjFeature.Fields.FindField("id"), j);
        //        featureCursor.InsertFeature(xjFeature);
        //    }

        //    IFeatureLayer xjFeatureLayer = new FeatureLayerClass();
        //    xjFeatureLayer.Name = xjShapeName;
        //    xjFeatureLayer.FeatureClass = xjFeatureClass;
        //    return xjFeatureLayer;
        //}

        #endregion

        #region 网络数据集相关 汤焱、苏鹏翔编写

        /// <summary>
        /// 获取（或创建）程序路径下的默认文件地理数据集
        /// </summary>
        /// <returns></returns>
        static public string GetDefaultGDB()
        {
            string tempDir = GetTempDirectory();
            string defaultGDBName = "Default.gdb";
            string defaultGDBPath = tempDir + defaultGDBName;

            if (!System.IO.Directory.Exists(defaultGDBPath))
            {
                IWorkspaceFactory pWorkspaceFactory = new FileGDBWorkspaceFactory();
                pWorkspaceFactory.Create(tempDir, defaultGDBName, null, 0);
            }

            return defaultGDBPath;
        }

        /// <summary>
        /// 在文件地理数据库中创建要素数据集
        /// </summary>
        /// <param name="workspace"></param>
        /// <param name="name"></param>
        /// <param name="spatialReference"></param>
        /// <returns></returns>
        static public IFeatureDataset CreateDatasetInGDB(IWorkspace workspace, string name, ISpatialReference spatialReference)
        {
            IFeatureWorkspace featureWorkspace = workspace as IFeatureWorkspace;
            IFeatureDataset featureDataset = featureWorkspace.CreateFeatureDataset(name, spatialReference);
            return featureDataset;
        }

        /// <summary>
        /// 要素类导入
        /// </summary>
        /// <param name="featureClass"></param>
        /// <param name="outPath"></param>
        /// <param name="name"></param>
        static public void ImportFeatureIntoGDB(IFeatureClass featureClass, string outPath, string name)
        {
            Geoprocessor gp = new Geoprocessor();

            FeatureClassToFeatureClass featureClassToFeatureClass = new FeatureClassToFeatureClass();
            featureClassToFeatureClass.in_features = featureClass;
            featureClassToFeatureClass.out_path = outPath;

            featureClassToFeatureClass.out_name = name;
            gp.OverwriteOutput = false;
            gp.Execute(featureClassToFeatureClass, null);
        }


        static public void CreateNetworkDataset(IFeatureClass roadFeature, string featureDatasetName = "Transportation")
        {
            // 获取默认数据库
            string defalutGDBPath = GetDefaultGDB();

            // 打开默认文件数据库
            IWorkspaceFactory workspaceFactory = new FileGDBWorkspaceFactory();
            IWorkspace workspace = workspaceFactory.OpenFromFile(defalutGDBPath, 0);
            IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace;

            // 创建要素数据集
            IFeatureDataset featureDataset = CreateDatasetInGDB(workspace, featureDatasetName, (roadFeature as IGeoDataset).SpatialReference);
            IGeoDataset geoDataset = (IGeoDataset)featureDataset;

            // 添加要素类至要素数据集
            ImportFeatureIntoGDB(roadFeature, defalutGDBPath + "\\" + featureDatasetName, (roadFeature as IDataset).Name);

            // 创建网络数据集
            IDENetworkDataset2 deNetworkDataset = new DENetworkDatasetClass();
            deNetworkDataset.Buildable = true;

            // 设置网络数据集的范围和空间参考
            IDEGeoDataset deGeoDataset = (IDEGeoDataset)deNetworkDataset;
            deGeoDataset.Extent = geoDataset.Extent;
            deGeoDataset.SpatialReference = geoDataset.SpatialReference;

            // 设置网络数据集的名字
            IDataElement dataElement = (IDataElement)deNetworkDataset;
            dataElement.Name = (roadFeature as IDataset).Name + "_ND";

            // 高程模型设置为无
            deNetworkDataset.ElevationModel = esriNetworkElevationModel.esriNEMNone;

            INetworkSource networkSource = CreateEdgeFeatureNetworkSource(((IDataset)roadFeature).Name);
            SetNetworkSourceWithoutSubtype(networkSource);

            List<INetworkSource> sourceList = new List<INetworkSource>();
            sourceList.Add(networkSource);
            IEvaluatedNetworkAttribute networkAttribute = CreateNetworkSourceAttribute(sourceList, "Length", "[Shape]", "");

            IArray array = new ArrayClass();
            array.Add(networkAttribute);
            deNetworkDataset.Attributes = array;

            IArray arraySource = new ArrayClass();
            arraySource.Add(networkSource);
            deNetworkDataset.Sources = arraySource;

            // 创建网络数据集
            IFeatureDatasetExtensionContainer fdxContainer = (IFeatureDatasetExtensionContainer)featureDataset;
            IFeatureDatasetExtension fdExtension = fdxContainer.FindExtension(esriDatasetType.esriDTNetworkDataset);
            IDatasetContainer2 datasetContainer2 = (IDatasetContainer2)fdExtension;
            IDEDataset deDataset = (IDEDataset)deNetworkDataset;
            INetworkDataset networkDataset = (INetworkDataset)datasetContainer2.CreateDataset(deDataset);

            // 创建成功后构建网络
            INetworkBuild networkBuild = (INetworkBuild)networkDataset;
            networkBuild.BuildNetwork(geoDataset.Extent);
        }

        /// <summary>
        /// 创建网络源对象
        /// </summary>
        /// <param name="featureClassName"></param>
        /// <returns></returns>
        static private INetworkSource CreateEdgeFeatureNetworkSource(string featureClassName)
        {
            INetworkSource edgeNetworkSource = new EdgeFeatureSourceClass();
            edgeNetworkSource.Name = featureClassName;
            // 类型
            edgeNetworkSource.ElementType = esriNetworkElementType.esriNETEdge;

            return edgeNetworkSource;
        }

        /// <summary>
        /// 设置网络连通性
        /// </summary>
        /// <param name="pNetworkSource"></param>
        static private void SetNetworkSourceWithoutSubtype(INetworkSource pNetworkSource)
        {
            IEdgeFeatureSource edgeFeatureSource = pNetworkSource as IEdgeFeatureSource;
            // 不使用子类
            edgeFeatureSource.UsesSubtypes = false;
            // 分组
            edgeFeatureSource.ClassConnectivityGroup = 1;
            // 使用终节点参与
            edgeFeatureSource.ClassConnectivityPolicy = esriNetworkEdgeConnectivityPolicy.esriNECPEndVertex;
        }

        /// <summary>
        /// 网络权重属性设置，多个源参与同一个网络数据集属性设置
        /// </summary>
        /// <param name="sourceList">源对象集合</param>
        /// <param name="strAttributeName">属性名称</param>
        /// <param name="strExpression">表达式</param>
        /// <param name="preLogic">逻辑表达式，可空</param>
        /// <returns></returns>
        static private IEvaluatedNetworkAttribute CreateNetworkSourceAttribute(List<INetworkSource> sourceList, string strAttributeName, string strExpression, string preLogic)
        {
            IEvaluatedNetworkAttribute pEvaluateNetworkAttribute;
            INetworkAttribute2 pNetworkAttribute;
            INetworkFieldEvaluator pNetFieldEval;
            INetworkConstantEvaluator pNetConsEval;

            pEvaluateNetworkAttribute = new EvaluatedNetworkAttributeClass();
            pNetworkAttribute = pEvaluateNetworkAttribute as INetworkAttribute2;
            pNetworkAttribute.Name = strAttributeName;
            //设置属性
            pNetworkAttribute.UsageType = esriNetworkAttributeUsageType.esriNAUTCost;
            pNetworkAttribute.DataType = esriNetworkAttributeDataType.esriNADTDouble;
            pNetworkAttribute.Units = esriNetworkAttributeUnits.esriNAUMeters;
            pNetworkAttribute.UseByDefault = true;

            // 计算表达式
            pNetFieldEval = new NetworkFieldEvaluatorClass();
            pNetFieldEval.SetExpression(strExpression, preLogic);

            //参与的每个源的计算表达式设置
            sourceList.ForEach(pEdgeNetworkSource =>
            {
                // 正向计算表达式
                pEvaluateNetworkAttribute.set_Evaluator(pEdgeNetworkSource, esriNetworkEdgeDirection.esriNEDAlongDigitized, (INetworkEvaluator)pNetFieldEval);
                pEvaluateNetworkAttribute.set_Evaluator(pEdgeNetworkSource, esriNetworkEdgeDirection.esriNEDAgainstDigitized, (INetworkEvaluator)pNetFieldEval);
            });

            pNetConsEval = new NetworkConstantEvaluatorClass();
            pNetConsEval.ConstantValue = 0;

            // 设置边，交汇点默认值为常数
            pEvaluateNetworkAttribute.set_DefaultEvaluator(esriNetworkElementType.esriNETEdge, (INetworkEvaluator)pNetConsEval);
            pEvaluateNetworkAttribute.set_DefaultEvaluator(esriNetworkElementType.esriNETJunction, (INetworkEvaluator)pNetConsEval);
            pEvaluateNetworkAttribute.set_DefaultEvaluator(esriNetworkElementType.esriNETTurn, (INetworkEvaluator)pNetConsEval);

            return pEvaluateNetworkAttribute;
        }

        public static IWorkspace OpenWorkspace(string strGDBName)//打开工作空间
        {
            // As Workspace Factories are Singleton objects, they must be instantiated with the Activator
            var workspaceFactory = System.Activator.CreateInstance(System.Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory")) as ESRI.ArcGIS.Geodatabase.IWorkspaceFactory;

            if (!System.IO.Directory.Exists(strGDBName))
            {
                MessageBox.Show("The workspace: " + strGDBName + " does not exist", "Workspace Error");
                return null;
            }

            IWorkspace workspace = null;
            try
            {

                workspace = workspaceFactory.OpenFromFile(strGDBName, 0);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Opening workspace failed: " + ex.Message, "Workspace Error");
            }

            return workspace;
        }

        /// <summary>
        /// Geodatabase function: open network dataset
        /// </summary>
        /// <param name="workspace">Input workspace</param>
        /// <param name="strNDSName">Input network dataset name</param>
        /// <returns>NetworkDataset</returns>
        /// 
        public static INetworkDataset OpenNetworkDataset(IWorkspace workspace, string featureDatasetName, string strNDSName)//打开工作空间中的网络数据集
        {
            // Obtain the dataset container from the workspace
            var featureWorkspace = workspace as IFeatureWorkspace;
            ESRI.ArcGIS.Geodatabase.IFeatureDataset featureDataset = featureWorkspace.OpenFeatureDataset(featureDatasetName);
            var featureDatasetExtensionContainer = featureDataset as ESRI.ArcGIS.Geodatabase.IFeatureDatasetExtensionContainer;
            ESRI.ArcGIS.Geodatabase.IFeatureDatasetExtension featureDatasetExtension = featureDatasetExtensionContainer.FindExtension(ESRI.ArcGIS.Geodatabase.esriDatasetType.esriDTNetworkDataset);
            var datasetContainer3 = featureDatasetExtension as ESRI.ArcGIS.Geodatabase.IDatasetContainer3;

            // Use the container to open the network dataset.
            ESRI.ArcGIS.Geodatabase.IDataset dataset = datasetContainer3.get_DatasetByName(ESRI.ArcGIS.Geodatabase.esriDatasetType.esriDTNetworkDataset, strNDSName);
            return dataset as ESRI.ArcGIS.Geodatabase.INetworkDataset;
        }

        /// <summary>
        /// Geodatabase function: get network dataset
        /// </summary>
        /// <param name="networkDataset">Input network dataset</param>
        /// <returns>DE network dataset</returns>		
        public static IDENetworkDataset GetDENetworkDataset(INetworkDataset networkDataset)
        {
            // Cast from the network dataset to the DatasetComponent
            IDatasetComponent dsComponent = networkDataset as IDatasetComponent;

            // Get the data element
            return dsComponent.DataElement as IDENetworkDataset;
        }

        /// <summary>
        /// Create NASolver and NAContext
        /// </summary>
        /// <param name="networkDataset">Input network dataset</param>
        /// <returns>NAContext</returns>
        public static void CreateSolverContext(INetworkDataset networkDataset, ref INAContext m_NAContext)
        {
            if (networkDataset == null) return;

            //Get the Data Element
            IDENetworkDataset deNDS = GetDENetworkDataset(networkDataset);

            INASolver naSolver = new NARouteSolver();
            m_NAContext = naSolver.CreateContext(deNDS, naSolver.Name);
            ((INAContextEdit)m_NAContext).Bind(networkDataset, new GPMessagesClass());
        }

        /// <summary>
        /// Set solver settings
        /// </summary>
        /// <param name="strNAClassName">NAClass name</param>
        /// <param name="inputFC">Input feature class</param>
        /// <param name="maxSnapTolerance">Max snap tolerance</param>
        public static void LoadNANetworkLocations(string strNAClassName, IFeatureClass inputFC, double maxSnapTolerance, INAContext m_NAContext)
        {
            INamedSet classes = m_NAContext.NAClasses;
            INAClass naClass = classes.get_ItemByName(strNAClassName) as INAClass;

            // delete existing Locations except if that a barriers
            naClass.DeleteAllRows();

            // Create a NAClassLoader and set the snap tolerance (meters unit)
            INAClassLoader classLoader = new NAClassLoader();
            classLoader.Locator = m_NAContext.Locator;
            if (maxSnapTolerance > 0) ((INALocator3)classLoader.Locator).MaxSnapTolerance = maxSnapTolerance;
            classLoader.NAClass = naClass;

            //Create field map to automatically map fields from input class to NAClass
            INAClassFieldMap fieldMap = new NAClassFieldMapClass();
            fieldMap.CreateMapping(naClass.ClassDefinition, inputFC.Fields);
            classLoader.FieldMap = fieldMap;

            // Avoid loading network locations onto non-traversable portions of elements
            INALocator3 locator = m_NAContext.Locator as INALocator3;
            locator.ExcludeRestrictedElements = true;
            locator.CacheRestrictedElements(m_NAContext);

            //Load Network Locations
            int rowsIn = 0;
            int rowsLocated = 0;
            IFeatureCursor featureCursor = inputFC.Search(null, true);
            classLoader.Load((ICursor)featureCursor, null, ref rowsIn, ref rowsLocated);

            //Message all of the network analysis agents that the analysis context has changed
            ((INAContextEdit)m_NAContext).ContextChanged();
        }
        public static void SetSolverSettings(ref INAContext m_NAContext, string costAttribute)//网络的属性设置
        {
            //Set Route specific Settings
            INASolver naSolver = m_NAContext.Solver;

            INARouteSolver cfSolver = naSolver as INARouteSolver;
            cfSolver.OutputLines = esriNAOutputLineType.esriNAOutputLineTrueShapeWithMeasure;

            // Set generic solver settings
            // Set the impedance attribute
            INASolverSettings naSolverSettings;
            naSolverSettings = naSolver as INASolverSettings;
            naSolverSettings.ImpedanceAttributeName = costAttribute;//成本设置

            // Set the OneWay Restriction if necessary
            IStringArray restrictions;
            restrictions = naSolverSettings.RestrictionAttributeNames;
            restrictions.RemoveAll();
            restrictions.Add("Oneway");
            naSolverSettings.RestrictionAttributeNames = restrictions;

            //Restrict UTurns
            naSolverSettings.RestrictUTurns = esriNetworkForwardStarBacktrack.esriNFSBNoBacktrack;
            naSolverSettings.IgnoreInvalidLocations = true;

            // Set the Hierarchy attribute

            // Do not forget to update the context after you set your impedance
            naSolver.UpdateContext(m_NAContext, GetDENetworkDataset(m_NAContext.NetworkDataset), new GPMessagesClass());
        }


        #endregion

    }
}
